package com.joe.xl.demo.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Foobar {
    private int n;

    public Foobar(int n) {
        this.n = n;
    }

    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void foo() throws InterruptedException {

        for (int i = 0; i < n; i++) {
            lock.lock();
            condition.signal();
            // printFoo.run() outputs "foo". Do not change or remove this line.
            System.out.println("foo");
            condition.await();
            lock.unlock();
        }
    }

    public void bar() throws InterruptedException {

        for (int i = 0; i < n; i++) {
            lock.lock();
            condition.signal();
            // printBar.run() outputs "bar". Do not change or remove this line.
            System.out.println("bar");
            condition.await();
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        Foobar foobar = new Foobar(5);
        Foo foo = new Foo(foobar);
        Bar bar = new Bar(foobar);

        new Thread(foo).start();
        new Thread(bar).start();
    }


    static class Foo implements Runnable {
        Foobar foobar;
        public Foo(Foobar foobar){this.foobar = foobar;}

        @Override
        public void run() {
            try {
                foobar.foo();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class Bar implements Runnable {
        private Foobar foobar;
        public Bar(Foobar foobar){this.foobar = foobar;}

        @Override
        public void run() {
            try {
                foobar.bar();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
